using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Threading;
using System.Text;

namespace phasor {



	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form {
		public phasor.Graph graph1;

		#region Generated Vareables

		private System.ComponentModel.IContainer components;

		

		private System.Windows.Forms.TabPage tabPage1;
		private System.Windows.Forms.NumericUpDown numericUpDown1;
		private System.Windows.Forms.NumericUpDown numericUpDown2;
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem menuItem2;
		private System.Windows.Forms.MenuItem menuItem3;
		private System.Windows.Forms.MenuItem menuItem4;
		private System.Windows.Forms.MenuItem menuItem5;
		private System.Windows.Forms.MenuItem menuItem6;
		private System.Windows.Forms.Button butClearRMaxRMin;
		private System.Windows.Forms.MenuItem menuItem7;
		private System.Windows.Forms.MenuItem menuItem8;
		private System.Windows.Forms.Label label1;
		private System.Windows.Forms.Label label2;
		private System.Windows.Forms.Label labState;
		private System.Windows.Forms.Label labSpeed;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label labZoom;
		private System.Windows.Forms.MenuItem menuItem10;
		private System.Windows.Forms.Label label10;
		private System.Windows.Forms.Label label11;
		private System.Windows.Forms.Label label9;
		private System.Windows.Forms.Label label18;
		private System.Windows.Forms.Label label13;
		private System.Windows.Forms.Label label14;


		#endregion

		
		private Thread workerThread;
		private Form2 form2;
		private bool _pause = false;

		private double _alpha;
		public double _dAlpha;
		internal int _n;
		private double E0;
		public bool _autoZoom;
		

		// The Constructor!
		public Form1() {
			InitializeComponent();
		}

		
		public void SetUpIniParam() {
			AutoZoom = false;

			n = 5;
			alpha = 0f;
			dAlpha = 0.0000051f;
			E0 = 1f;

			//ClearMaxMin();
			ClearRMaxRMin();

			graph1.SetupWorld_1();

			if (form2 != null && !form2.Closed) {
				form2.SyncFromForm1();
			}
			
			//Pause = false;
		}
		

		#region Data generation



        
        long updateIntervle = 25;
        long lastUpdate = 25;

		public void dataUpdateLoop() {
			while (true) {
				//Thread.Sleep(new TimeSpan(9000));
				//Thread.SpinWait(spinWait);

                if (!Pause)
                {
                    alpha += dAlpha;
                }
                else
                {
                    Thread.Sleep(50);
                }

				generateData(n, E0, alpha);
                

                if (Environment.TickCount - lastUpdate > updateIntervle)
                {
                    graph1.Invalidate();
                    lastUpdate = Environment.TickCount;
                }
			}
		}

		public static double AlphaToPhi(double alpha, int n) {
			return 2f * alpha / (double)(n - 1);
		}
		public static double PhiToAlpha(double phi, int n) {
			return (double)(n - 1) * phi / 2f;
		}

		float xMin, xMax;
		float yMin, yMax;

		private void findTrueMax() {
			
		}

		private void ClearMaxMin() {
			xMin = float.MaxValue;
			xMax = float.MinValue;
			yMin = float.MaxValue;
			yMax = float.MinValue;
		}

		private void CheckSetMaxMin(PointD pD) {
			PointF p = new PointF((float)pD.X, (float)pD.Y);

			if (p.X < xMin) {
				xMin = p.X;
			}

			if (p.X > xMax) {
				xMax = p.X;
			}

			if (p.Y < yMin) {
				yMin = p.Y;
			}

			if (p.Y > yMax) {
				yMax = p.Y;
			}
		}

		ArrayList tempPhasors = new ArrayList();
		
		// Algorythum to generate phasors
		private void generateData(int n, double E0, double alpha) {
			if (n < 2) return;

			double phi = AlphaToPhi(alpha, n);

			double sinRad = Math.Sin(phi);
			double cosRad = Math.Cos(phi);

			// Needed to stop errors from happening when autozoom is enabled
			// in the midle of this methods exsicution
			bool autoZoomEnabledPreData = false; 

			if (AutoZoom) {
				autoZoomEnabledPreData = true;
				ClearMaxMin();
			}
			

			
			tempPhasors.Clear();

			// First point
			PointD p0, p1, p2_PreRotation;
			tempPhasors.Add(new PointD(0, 0)); 		 // n=0.
			if (AutoZoom) CheckSetMaxMin((PointD)tempPhasors[tempPhasors.Count - 1]);
			
			tempPhasors.Add(new PointD(E0, 0)); // n=1
			if (AutoZoom) CheckSetMaxMin((PointD)tempPhasors[tempPhasors.Count - 1]);

			for (int N = 2; N <= n; N++) {
				// The tail of the phasor befor the one we are curently consturcting
				p0 = (PointD)tempPhasors[tempPhasors.Count - 2];
			
				// The head of the phasor befor the one we are curently constructing
				p1 = (PointD)tempPhasors[tempPhasors.Count - 1];

				// The head of the phasor we are constructing (pre-rotation) as if phi = 0
				// This is done by adding the x and y components of the previus phasor to the
				// p1 (the head of the previus phasor)
				p2_PreRotation = new PointD(p1.X + (p1.X - p0.X), p1.Y + (p1.Y - p0.Y));

				// Rotate p2_PreRotation and add it to the colection
				tempPhasors.Add(graph1.Rotate(p2_PreRotation, p1, sinRad, cosRad));

				if (AutoZoom) CheckSetMaxMin((PointD)tempPhasors[tempPhasors.Count - 1]);				
			}

			// Switch old set of phasors for new set just generated
			lock (graph1.Phasors) {
				ArrayList saveOldPhasors = graph1.Phasors;
				graph1.Phasors = tempPhasors;
				tempPhasors = saveOldPhasors;
			}

			updateStats();

			if (AutoZoom && autoZoomEnabledPreData) {
				SetAutoZoom2();
			}


			
		}


		private void SetAutoZoom1() {
		// Option zooms and pans for close fit
			float xRange = xMax - xMin;
			float yRange = yMax - yMin;

			if (xMax == 0 && xMin == 0 && yMax == 0 && yMin == 0) return;

			if (xRange > 0 && yRange > 0) {

				float X_to_Y = xRange / yRange;
				float graphX_to_Y = graph1.GetWorldWidth() / graph1.GetWorldHeight();

				if (X_to_Y > graphX_to_Y) {
					graph1.SetWorldWindowX_FixedAspect(xMin, xMax, yMin + yRange / 2f); 

				} else {
					graph1.SetWorldWindowY_FixedAspect(yMin, yMax, xMin + xRange / 2f); 
				}
			} else if (yRange <= 0) {
				graph1.SetWorldWindowX_FixedAspect(xMin, xMax, yMin + yRange / 2f);
			} else if (xRange <= 0) {
				graph1.SetWorldWindowY_FixedAspect(yMin, yMax, xMin + xRange / 2f);
			}
		}

		private void SetAutoZoom2() {
		// Option zooms in and out to include all points but does not change center location
			if (xMax == 0 && xMin == 0 && yMax == 0 && yMin == 0) {
				return;
			}

			// Get curent world center
			//PointF C = graph1.GetWorldCenter();
			PointF C = new PointF(0.5f, 0);
			
			float xMaxToC = xMax - C.X;
			float xMinToC = C.X - xMin;
			float yMaxToC = yMax - C.Y;
			float yMinToC = C.Y - yMin;

			float xRange, yRange;

			if (xMaxToC > xMinToC) {
				xRange = xMaxToC * 2f;
			} else {
				xRange = xMinToC * 2f;
			}

			if (yMaxToC > yMinToC) {
				yRange = yMaxToC * 2f;
			} else {
				yRange = yMinToC * 2f;
			}

			if (xRange > 0 && yRange > 0) {
				
				float X_to_Y = xRange / yRange;
				float graphX_to_Y = graph1.GetWorldWidth() / graph1.GetWorldHeight();

				if (X_to_Y > graphX_to_Y) {
					graph1.SetWorldWindowX_FixedAspect(C.X - xRange / 2f, C.X + xRange / 2f, C.Y); 
				} else {
					graph1.SetWorldWindowY_FixedAspect(C.Y - yRange / 2f, C.Y + yRange / 2f, C.X); 
				}
			} else if (yRange <= 0) {
				graph1.SetWorldWindowX_FixedAspect((float)xMin, (float)xMax, (float)yMin + (float)yRange / 2f);
			} else if (xRange <= 0) {
				graph1.SetWorldWindowY_FixedAspect((float)yMin, (float)yMax, (float)xMin + (float)xRange / 2f);
			}



		}


		
		#endregion

		#region Input handleing



		internal bool ProcessDialogKey_Internal(Keys key) {
			return ProcessDialogKey(key);
		}
		
		protected override bool ProcessDialogKey(Keys key) {
			bool handled = false;

			if (key == Keys.Right) { // RIGHT [Increase n]
				if (n < 10000) {
					n += 1;
				}
				handled = true;

			} else if (key == Keys.Left) { // LEFT [Decrease n]
				if (n > 2) {
					n -= 1;
				}
				handled = true;
						
			} else if (key == Keys.Up) { // UP [Increase speed]
				if (form2 != null && !form2.Closed) {
					if (form2.trackSpeed.Value < form2.trackSpeed.Maximum) {
						form2.trackSpeed.Value += 1;
					}
				} else {
					int curSpeed = Form2.dAlpha_to_trackSpeed(dAlpha);
					if (curSpeed < 1000) {
						dAlpha = Form2.TrackSpeed_to_dAlpha(curSpeed + 1);
					}
				}
				handled = true;

			} else if (key == Keys.Down) { // DOWN	[Decrease speed]
				if (form2 != null && !form2.Closed) {
					if (form2.trackSpeed.Value > form2.trackSpeed.Minimum) {
						form2.trackSpeed.Value -= 1;
					}
				} else {
					int curSpeed = Form2.dAlpha_to_trackSpeed(dAlpha);
					if (curSpeed > -1000) {
						dAlpha = Form2.TrackSpeed_to_dAlpha(curSpeed - 1);
					}
				}
				handled = true;

			} else if (key == Keys.S) { // Zero speed
				if (form2 != null && !form2.Closed) {
					form2.trackSpeed.Value = 0;
				} else {
					dAlpha = 0f;
				}
				handled = true;

			} else if (key == Keys.Space) { // Pause
				Pause = !Pause;
				handled = true;
			
			} else if (key == Keys.C) { // Clear MAx min
				ClearRMaxRMin();
				handled = true;
				
			} else if (key == Keys.R) {
				SetUpIniParam();
				handled = true;

			} else if (key == Keys.Z) {
				AutoZoom = !AutoZoom;
				handled = true;
				
			} else if (key == Keys.D) {
				if (!AutoZoom) {
					if (zForm != null && !form2.Closed) {
						if (zForm.trackZoom.Value < zForm.trackZoom.Maximum - 3) {
							zForm.trackZoom.Value += 4;
						}
					} else {
						graph1.SetScaleFromLinear(graph1.GetLinearScale() + 4);
					}
				}
				handled = true;

			} else if (key == Keys.A) {
				if (!AutoZoom) {
					if (zForm != null && !zForm.Closed) {
						if (zForm.trackZoom.Value > zForm.trackZoom.Minimum + 3) {
							zForm.trackZoom.Value -= 4;
						}
					} else {
						graph1.SetScaleFromLinear(graph1.GetLinearScale() - 4);
					}
				}
				handled = true;



			} else {
				//Console.WriteLine(key.ToString() + " | " + e.KeyValue.ToString());
				handled = false;
			}

			return handled;
		}

		#endregion

		public bool Pause {
			get { return _pause; }
			set {
				_pause = value;
				if (form2 != null && !form2.Closed) {
					// Make sure button and other controls on form2 are as they shuld be
					form2.UpdatePauseInfo();
				}
				if (value) {
					labState.Text = "Paused";
					labState.ForeColor = Color.DarkRed;
					pForm.SyncNSlitsWithForm1();
					pForm.SyncPhaseWithForm1();
					pForm.Show();
					this.Focus();
				} else {
					labState.Text = "Running";
					labState.ForeColor = Color.DarkGreen;
					pForm.Hide();
				}
			}
		}

		
		int manualLinearZoom = int.MinValue;

		public bool AutoZoom {
			get { 
				return _autoZoom; 
			}
			set {
							
				if (value) {
					labZoom.Text = "Auto";
					manualLinearZoom = graph1.GetLinearScale();
					_autoZoom = value; // Important pos [LAST]
				} else {
					_autoZoom = value; // Important pos [FIRST]
					labZoom.Text = "Manual";
					graph1.SetupWorld_1();
					if (manualLinearZoom != int.MinValue) {
						graph1.SetScaleFromLinear(manualLinearZoom);
					}
				}

				if (zForm != null && !zForm.Closed) {
					// Make sure button and other controls on form2 are as they shuld be
					zForm.trackZoom.Enabled = !value;
				}
				
			}
		}



		#region Public Fields

		public int n {
			get { return _n; }
			set {
				// Don't let phase change
				double curPhi = AlphaToPhi(alpha, _n);
				
				
				_n = value;
			
				// Update Fomr2 and lables
				if (Pause && pForm != null && !pForm.Closed && pForm.Visible) {
					pForm.SyncNSlitsWithForm1();
				}

				_alpha = PhiToAlpha(curPhi, value);
			}
		}

		public double alpha {
			get { return _alpha; }
			set {
				// Restrict phi range between 0 and 2Pi inclusive
				bool change = false;
				double phi = AlphaToPhi(alpha, n);
				
				if (phi < 0) {
					phi = (float)(2.0 * Math.PI + phi);
					change = true;
				}
				
				if (phi >= 2f * Math.PI) {
					int nth = (int)(phi / (2f * Math.PI));
					phi = (float)(phi - nth * 2.0 * Math.PI);
					change = true;
				}
				
				if (change) {
					_alpha = PhiToAlpha(phi, n);
				} else {
					_alpha = value;
				}

				// Update Form2 and lables
				if (Pause && pForm != null && !pForm.Closed && pForm.Visible) {
					//pForm.SyncPhaseWithForm1();
				}
			}
		}

		public double dAlpha {
			get { return _dAlpha; }
			set {
				_dAlpha = value;
				labSpeed.Text = Form2.dAlpha_to_trackSpeed(_dAlpha).ToString();
				if (_dAlpha == 0f) {
					labSpeed.ForeColor = Color.DarkRed;
				} else {
					labSpeed.ForeColor = Color.Black;
				}
			}
		}

		#endregion






		private double RMax {
			get { return _RMax; }
			set {
				_RMax = value;
				_RMax_Phi = AlphaToPhi(alpha, n);

				graph1.UpdateRMax(Math.Round(_RMax, 5).ToString() + " @ " + Math.Round(_RMax_Phi, 5).ToString());
			}
		}	

		private double RMin {
			get { return _RMin; }
			set {
				_RMin = value;
				_RMin_Phi = AlphaToPhi(alpha, n);

				graph1.UpdateRMin(Math.Round(_RMin, 5).ToString() + " @ " + Math.Round(_RMin_Phi, 5).ToString());
			}
		}

		public void ClearRMaxRMin() {
			_RMax = double.MinValue;
			_RMin = double.MaxValue;
		}

		private void updateRMinMax(double R) {
			if (R > RMax) { 
				RMax = R;
			}
			if (R < RMin) {
				RMin = R;
			}
		}

		private void updateStats() {
			PointD pL = (PointD)graph1.Phasors[graph1.Phasors.Count - 1];


			graph1.UpdatePosInfo( 
				Math.Round(AlphaToPhi(alpha, n), 5), 
				Math.Round(Math.Pow(pL.X * pL.X + pL.Y * pL.Y, 0.5), 5));

			// Update R on form1
			updateRMinMax(Math.Pow(pL.X * pL.X + pL.Y * pL.Y, 0.5));
		
		}








		#region Generated Code

		protected override void Dispose( bool disposing ) {
			workerThread.Abort();
			if( disposing ) {
				if (components != null) {
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent() {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.numericUpDown2 = new System.Windows.Forms.NumericUpDown();
            this.tabPage1 = new System.Windows.Forms.TabPage();
            this.numericUpDown1 = new System.Windows.Forms.NumericUpDown();
            this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.menuItem4 = new System.Windows.Forms.MenuItem();
            this.menuItem3 = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.menuItem7 = new System.Windows.Forms.MenuItem();
            this.menuItem8 = new System.Windows.Forms.MenuItem();
            this.menuItem10 = new System.Windows.Forms.MenuItem();
            this.menuItem5 = new System.Windows.Forms.MenuItem();
            this.menuItem6 = new System.Windows.Forms.MenuItem();
            this.butClearRMaxRMin = new System.Windows.Forms.Button();
            this.label3 = new System.Windows.Forms.Label();
            this.labZoom = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.labState = new System.Windows.Forms.Label();
            this.labSpeed = new System.Windows.Forms.Label();
            this.label10 = new System.Windows.Forms.Label();
            this.label11 = new System.Windows.Forms.Label();
            this.label9 = new System.Windows.Forms.Label();
            this.label18 = new System.Windows.Forms.Label();
            this.label13 = new System.Windows.Forms.Label();
            this.label14 = new System.Windows.Forms.Label();
            this.graph1 = new phasor.Graph();
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).BeginInit();
            this.SuspendLayout();
            // 
            // numericUpDown2
            // 
            this.numericUpDown2.Location = new System.Drawing.Point(0, 0);
            this.numericUpDown2.Name = "numericUpDown2";
            this.numericUpDown2.Size = new System.Drawing.Size(120, 20);
            this.numericUpDown2.TabIndex = 0;
            // 
            // tabPage1
            // 
            this.tabPage1.Location = new System.Drawing.Point(0, 0);
            this.tabPage1.Name = "tabPage1";
            this.tabPage1.Size = new System.Drawing.Size(200, 100);
            this.tabPage1.TabIndex = 0;
            // 
            // numericUpDown1
            // 
            this.numericUpDown1.Location = new System.Drawing.Point(0, 0);
            this.numericUpDown1.Name = "numericUpDown1";
            this.numericUpDown1.Size = new System.Drawing.Size(120, 20);
            this.numericUpDown1.TabIndex = 0;
            // 
            // mainMenu1
            // 
            this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem1,
            this.menuItem7,
            this.menuItem5});
            // 
            // menuItem1
            // 
            this.menuItem1.Index = 0;
            this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem4,
            this.menuItem3,
            this.menuItem2});
            this.menuItem1.Text = "&File";
            // 
            // menuItem4
            // 
            this.menuItem4.Index = 0;
            this.menuItem4.Text = "&Reset";
            this.menuItem4.Click += new System.EventHandler(this.menuItem4_Click);
            // 
            // menuItem3
            // 
            this.menuItem3.Index = 1;
            this.menuItem3.Text = "-";
            // 
            // menuItem2
            // 
            this.menuItem2.Index = 2;
            this.menuItem2.Text = "E&xit";
            this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
            // 
            // menuItem7
            // 
            this.menuItem7.Index = 1;
            this.menuItem7.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem8,
            this.menuItem10});
            this.menuItem7.Text = "&View";
            this.menuItem7.Popup += new System.EventHandler(this.menuItem7_Popup);
            // 
            // menuItem8
            // 
            this.menuItem8.Index = 0;
            this.menuItem8.Text = "&Zoom bar";
            this.menuItem8.Click += new System.EventHandler(this.menuItem8_Click);
            // 
            // menuItem10
            // 
            this.menuItem10.Index = 1;
            this.menuItem10.Text = "&Speed bar";
            this.menuItem10.Click += new System.EventHandler(this.menuItem10_Click);
            // 
            // menuItem5
            // 
            this.menuItem5.Index = 2;
            this.menuItem5.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem6});
            this.menuItem5.Text = "&Help";
            // 
            // menuItem6
            // 
            this.menuItem6.Index = 0;
            this.menuItem6.Text = "&About PhasorCS...";
            this.menuItem6.Click += new System.EventHandler(this.menuItem6_Click);
            // 
            // butClearRMaxRMin
            // 
            this.butClearRMaxRMin.BackColor = System.Drawing.Color.White;
            this.butClearRMaxRMin.Location = new System.Drawing.Point(90, 232);
            this.butClearRMaxRMin.Name = "butClearRMaxRMin";
            this.butClearRMaxRMin.Size = new System.Drawing.Size(50, 18);
            this.butClearRMaxRMin.TabIndex = 18;
            this.butClearRMaxRMin.TabStop = false;
            this.butClearRMaxRMin.Text = "Clear";
            this.butClearRMaxRMin.UseVisualStyleBackColor = false;
            this.butClearRMaxRMin.Click += new System.EventHandler(this.butClearRMaxRMin_Click);
            // 
            // label3
            // 
            this.label3.BackColor = System.Drawing.Color.White;
            this.label3.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label3.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.label3.Location = new System.Drawing.Point(16, 145);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(48, 18);
            this.label3.TabIndex = 31;
            this.label3.Text = "Zoom:";
            this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // labZoom
            // 
            this.labZoom.BackColor = System.Drawing.Color.Transparent;
            this.labZoom.Cursor = System.Windows.Forms.Cursors.Hand;
            this.labZoom.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labZoom.Location = new System.Drawing.Point(88, 145);
            this.labZoom.Name = "labZoom";
            this.labZoom.Size = new System.Drawing.Size(66, 18);
            this.labZoom.TabIndex = 30;
            this.labZoom.Text = "Manual";
            this.labZoom.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.labZoom.Click += new System.EventHandler(this.labZoom_Click);
            // 
            // label1
            // 
            this.label1.BackColor = System.Drawing.Color.White;
            this.label1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label1.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.label1.Location = new System.Drawing.Point(16, 109);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(46, 18);
            this.label1.TabIndex = 29;
            this.label1.Text = "State:";
            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // label2
            // 
            this.label2.BackColor = System.Drawing.Color.White;
            this.label2.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label2.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.label2.Location = new System.Drawing.Point(16, 127);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(48, 18);
            this.label2.TabIndex = 28;
            this.label2.Text = "Speed:";
            this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // labState
            // 
            this.labState.BackColor = System.Drawing.Color.Transparent;
            this.labState.Cursor = System.Windows.Forms.Cursors.Hand;
            this.labState.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labState.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(64)))), ((int)(((byte)(0)))));
            this.labState.Location = new System.Drawing.Point(88, 109);
            this.labState.Name = "labState";
            this.labState.Size = new System.Drawing.Size(66, 18);
            this.labState.TabIndex = 6;
            this.labState.Text = "Running";
            this.labState.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.labState.Click += new System.EventHandler(this.labState_Click);
            // 
            // labSpeed
            // 
            this.labSpeed.BackColor = System.Drawing.Color.Transparent;
            this.labSpeed.Cursor = System.Windows.Forms.Cursors.Hand;
            this.labSpeed.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.labSpeed.Location = new System.Drawing.Point(88, 127);
            this.labSpeed.Name = "labSpeed";
            this.labSpeed.Size = new System.Drawing.Size(66, 18);
            this.labSpeed.TabIndex = 2;
            this.labSpeed.Text = "-10000";
            this.labSpeed.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            this.labSpeed.Click += new System.EventHandler(this.labSpeed_Click);
            // 
            // label10
            // 
            this.label10.BackColor = System.Drawing.Color.White;
            this.label10.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label10.Location = new System.Drawing.Point(23, 24);
            this.label10.Name = "label10";
            this.label10.Size = new System.Drawing.Size(66, 18);
            this.label10.TabIndex = 29;
            this.label10.Text = "n(slits):";
            this.label10.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            // 
            // label11
            // 
            this.label11.BackColor = System.Drawing.Color.White;
            this.label11.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label11.Location = new System.Drawing.Point(9, 44);
            this.label11.Name = "label11";
            this.label11.Size = new System.Drawing.Size(80, 18);
            this.label11.TabIndex = 28;
            this.label11.Text = "Phase(rad):";
            this.label11.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            // 
            // label9
            // 
            this.label9.BackColor = System.Drawing.Color.White;
            this.label9.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label9.Location = new System.Drawing.Point(35, 64);
            this.label9.Name = "label9";
            this.label9.Size = new System.Drawing.Size(54, 16);
            this.label9.TabIndex = 30;
            this.label9.Text = "|R|:";
            this.label9.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
            // 
            // label18
            // 
            this.label18.BackColor = System.Drawing.Color.White;
            this.label18.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label18.Location = new System.Drawing.Point(16, 6);
            this.label18.Name = "label18";
            this.label18.Size = new System.Drawing.Size(62, 18);
            this.label18.TabIndex = 36;
            this.label18.Text = "Position";
            this.label18.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // label13
            // 
            this.label13.BackColor = System.Drawing.Color.White;
            this.label13.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label13.Location = new System.Drawing.Point(17, 92);
            this.label13.Name = "label13";
            this.label13.Size = new System.Drawing.Size(76, 18);
            this.label13.TabIndex = 37;
            this.label13.Text = "Simulation";
            this.label13.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // label14
            // 
            this.label14.BackColor = System.Drawing.Color.White;
            this.label14.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label14.Location = new System.Drawing.Point(17, 174);
            this.label14.Name = "label14";
            this.label14.Size = new System.Drawing.Size(82, 18);
            this.label14.TabIndex = 38;
            this.label14.Text = "|R| Max-Min";
            this.label14.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
            // 
            // graph1
            // 
            this.graph1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.graph1.BackColor = System.Drawing.Color.White;
            this.graph1.Cursor = System.Windows.Forms.Cursors.Arrow;
            this.graph1.Location = new System.Drawing.Point(0, 0);
            this.graph1.Name = "graph1";
            this.graph1.Size = new System.Drawing.Size(632, 401);
            this.graph1.TabIndex = 0;
            this.graph1.TabStop = false;
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(7, 13);
            this.BackColor = System.Drawing.Color.White;
            this.ClientSize = new System.Drawing.Size(631, 401);
            this.Controls.Add(this.label14);
            this.Controls.Add(this.labSpeed);
            this.Controls.Add(this.label3);
            this.Controls.Add(this.labZoom);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.labState);
            this.Controls.Add(this.label13);
            this.Controls.Add(this.label10);
            this.Controls.Add(this.label11);
            this.Controls.Add(this.label9);
            this.Controls.Add(this.label18);
            this.Controls.Add(this.butClearRMaxRMin);
            this.Controls.Add(this.graph1);
            this.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.KeyPreview = true;
            this.Menu = this.mainMenu1;
            this.MinimumSize = new System.Drawing.Size(330, 400);
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "PhasorCS 1.1";
            this.Load += new System.EventHandler(this.Form1_Load_1);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            this.Move += new System.EventHandler(this.Form1_Move);
            this.Resize += new System.EventHandler(this.Form1_Resize);
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown2)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.numericUpDown1)).EndInit();
            this.ResumeLayout(false);

		}
		#endregion
		[STAThread]
		static void Main() {
			//Application.Run(new Form1());
			SingleInstance.SingleApplication.Run(new Form1());

		}

		
		#endregion
		
		private void showControlForm() {
			if (form2 == null || form2.Closed) {
				form2 = new Form2();
				form2.Owner = this;
				form2.Show();
			} else {
				//form2.Visible 
				form2.Show();
			}
		}



		private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
			workerThread.Abort();
		}

		private void menuItem2_Click(object sender, System.EventArgs e) {
			this.Close();
		}

		private void menuItem4_Click(object sender, System.EventArgs e) {
			SetUpIniParam();
			graph1.SetupWorld_1();
		}

		Help help1;

		private void menuItem6_Click(object sender, System.EventArgs e) {
			//MessageBox.Show("PhasorCS\n\nCopyright 2004 - Mark Samuelson");
			if (help1 == null || help1.Closed) {
				help1 = new Help();
				help1.Owner = this;
				help1.Show();
			} else {
				//form2.Visible 
				help1.Show();
			}
		}



		private void butClearRMaxRMin_Click(object sender, System.EventArgs e) {
			ClearRMaxRMin();
		}

		private void labState_Click(object sender, System.EventArgs e) {
			Pause = !Pause;
		}

		private void labSpeed_Click(object sender, System.EventArgs e) {
			//dAlpha = 0f;
			form2.trackSpeed.Value = 0;
		}

		private void menuItem8_Click(object sender, System.EventArgs e) {
			if (zForm.Visible) {
				zForm.Hide();
			} else {
				zForm.Show();
			}
		}

		ZoomForm zForm;

		private void showZoomForm() {
			if (zForm == null || zForm.Closed) {
				zForm = new ZoomForm();
				zForm.form1 = this;
				zForm.Owner = this;
				zForm.Show();
			} else {
				//form2.Visible 
				zForm.Show();
			}
		}
		


		PositionForm pForm;

		private void showPositionForm() {
			if (pForm == null || pForm.Closed) {
				pForm = new PositionForm();
				pForm.form1 = this;
				pForm.Owner = this;
				pForm.Show(); // Show temperarly so that the first time it is show there is no flass do to JIT compiler
				pForm.Hide();
			} else {
				//form2.Visible 
				pForm.Show();
			}
		}

		private void Form1_Load_1(object sender, System.EventArgs e) {
			showControlForm();
			showPositionForm();
			showZoomForm();

			SetUpIniParam();

			workerThread = new Thread(new ThreadStart(dataUpdateLoop));
			workerThread.Start();

			//SetUpIniParam();
		}

		private void labZoom_Click(object sender, System.EventArgs e) {
			AutoZoom = !AutoZoom;
		}

		private void menuItem7_Popup(object sender, System.EventArgs e) {
			menuItem8.Checked = zForm.Visible;
			menuItem10.Checked = form2.Visible;
		}



		private void Form1_Move(object sender, System.EventArgs e) {
			setSubFormsPos();
		}

		private void Form1_Resize(object sender, System.EventArgs e) {
			setSubFormsPos();
		}

		private void setSubFormsPos() {
			if (pForm != null && !pForm.Closed) {
				pForm.SetPositionOnOwner();
			}

			if (zForm != null && !zForm.Closed) {
				zForm.SetPositionOnOwner();
			}
			
			if (form2 != null && !form2.Closed) {
				form2.SetPositionOnOwner();
			}
		}



		public void NSlitsButton_Click() {
			Pause = true;
			pForm.SetFocusOnNSlits();
		}
		
		public void PhaseButton_Click() {
			Pause = true;
			pForm.SetFocusOnPhase();
		}

		private double _RMax;
		private double _RMax_Phi;
		private double _RMin;
		private double _RMin_Phi;

		public void RMaxButton_Click() {
			_pause = true;
			alpha = PhiToAlpha(_RMax_Phi, n);
			Pause = true;
		}

		public void RMinButton_Click() {
			_pause = true;
			alpha = PhiToAlpha(_RMin_Phi, n);
			Pause = true;
		}




		private void menuItem10_Click(object sender, System.EventArgs e) {
			if (form2.Visible) {
				form2.Hide();
			} else {
				form2.Show();
			}
		}

	}


	public class PointD {
		public double X, Y;
		public PointD(double x, double y) {
			X = x;
			Y = y;
		}

		public static PointF ToPointF(PointD pD) {
			return new PointF((float)pD.X, (float)pD.Y);
		}
	}
}
